home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
331_01
/
edit.c
< prev
next >
Wrap
Text File
|
1990-06-12
|
22KB
|
809 lines
/*
HEADER: CUG999.03;
TITLE: SE (nee E) screen editor
DATE: 5/19-87;
DESCRIPTION: "Text buffer editing routines for se"
VERSION: 1.00;
SYSTEM: MS-DOS;
FILENAME: EDIT.C;
SEE-ALSO: SE.C
AUTHORS: G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
*/
/*
e/qed/ged/se screen editor
(C) G. Nigel Gilbert, MICROLOGY, 1981
August-December 1981
FUNCTIONS: movechar, moveline, dojump, jumpline,
movepage, moveword, insertchar, replchar, deletechar,
deleteword, linedelete, crdelete, crinsert, adjustc, sync
*/
/* Earlier versions had the capabiltiy of editing text containing embedded
* tabs. In that case the character index into text[] is less in magnitude
* than cursorx. Due partly to the addition of new functions, charn and
* cursorx are used interchangably in this version. This version converts
* tabs to spaces at the time the file is read. The capability of editing
* tabs might be restored as an option in a future version, but probably a
* better way is to do an automatic entab at disc write time for those who
* want tabs. The only advantage of embedded tabs is that they save disc
* space. They mess up everything else. The keyboard tab key is a cursor
* positioning command in this version. It does not store anyting. g.o.
*/
#include <stdio.h>
#include <ctype.h>
#include "ged.h"
/* move cursor by 'move' columns to the right return YES unless going off text
*/
movechar(move)
int move;
{
int cp, len, result, j;
cp = charn + move;
result = YES;
if ( cp < 0 ) {
if (cline > 1) {
charn = strlen(getline(cline-1));
moveline(-1);
}
}
/* The "cursor right one char" command adds trailing spaces as needed to
* provide free cursor movement. New characters would be lost if preceeded
* by a '\0'.
*/
else if ( cp > ( len = strlen(text) ) ) {
if(!trail && move == 1) {
sync(cp);
resetcursor();
return YES;
}
else {
charn = 0;
result = moveline(1);
return result;
}
}
else {
sync(cp); /* move +/- one on same line */
resetcursor();
return result;
}
}
/* calculate line number at the top and bottom of screen. The lines in that
* span are read from disc if not already in memory.
*
* It is convenient to be able to scroll
* by page for a few pages then page back to the original line with the
* cursor returning to its original position. The program works
* that way for page scrolls.
*/
calp()
{
if (cursory < topline)
cursory = topline;
if ( (cursory - topline) > (cline - 1) )
cursory = topline + (cline - 1); /* near bof */
pfirst = loc(cline + topline - cursory, 0);
plast = loc(pfirst + SHEIGHT - topline, 0);
if ( (cursory - topline) > (plast - pfirst) )
calp(--cursory); /* neaar eof */
return;
}
/* Move cursor by '+/- move' lines, + is downward.
* return YES if Ok, NO if going off text.
*
* Set 'cursory' to the preferred cursor y value before the call. The
* preferred location is not always be used. There are conditions near
* beginning and end of file when it cannot be used. A scroll
* placing the y cursor in the preferred positiion can be forced to
* the extent possible by setting plast=-1 before the call. The
* preferred value will otherwise not be used if a one-line
* scroll suffices, or if the new cursor position is already somewhere
* on the existing display. The minimization of scrolling is desirable
* from a speed standpoint. It also minimizes eye fatigue.
*
* The window movement is normally purely vertical, but there are
* exceptions. If 'charn' has recently changed then horizontal
* display motion may result also. If 'trail' is true then horizontal
* motion will often result due to the differing line lengths if
* the lines are long. To cause horizontal adjstment on the new
* line, set charn before the call to moveline(). It is unnecessary
* to call sync().
*
* moveline() assumes that the existing physical display is correct and
* current. It can't be called to show the result of an editng operation.
*
* It is assumed that the scroll function is faster than a
* rewrite, so scrolling is used when possible. Good high-level portability
* could be achieved by writing a low-level scroll function which might
* actually do a rewrite when the hardware scroll function is missing.
* The program is being restructured so that all hardware specific
* display and terminal functions are in term.c.
*/
moveline(move)
int move;
{
int line, i, oldoff, sav, ocline;
puttext();
ocline = cline;
cline = loc(cline, move); /* read from disc if necessary */
move = cline - ocline;
sav = curson(NO);
/* gettext adds trailing spaces if needed for free cursor motion */
gettext(cline, charn);
sync(charn);
if (plast < 0)
pfirst = -1;
if (pfirst < 0)
plast = -1;
oldoff = lastoff;
lastoff = calcoffset(charn);
if (blocking && ( move != 1 && move != -1) )
oldoff = -1; /* force a complete rewrite if reverse field too complex */
if (oldoff == lastoff && cline >= pfirst && cline <= plast ) {
/* the new cursor position is already on the screen */
if (blocking) /* the vacated line may become unmarked */
putline(ocline, cursory, NULL);
cursory = (cline - pfirst) + topline;
calp();
if (blocking) /* the new line may become marked */
putline(cline, cursory, NULL);
}
/* scroll down and add one line at top */
/* the old cursor can be anywhere on the screen */
else if (oldoff == lastoff && cline == pfirst -1) {
if (blocking) /* the vacated line may become unmarked */
putline(ocline, cursory, NULL);
scrolldown(topline);
cursory = topline;
putline(cline,topline,text);
calp();
}
/* scroll up and add one line at bottom */
else if (oldoff == lastoff && cline == plast + 1) {
if (blocking) /* the vacated line may become unmarked */
putline(ocline, cursory, NULL);
scrollup(topline);
cursory = SHEIGHT;
putline(cline, SHEIGHT, text);
calp();
}
/* Vertical screen motion of 0 or more than 1 line, or horiz scrolling. */
/* This case uses the preferred y cursor position if possible */
/* moves of 0 are used to re-establish valid environment */
else {
calp();
putpage();
}
putlineno(cline); /* update line and column no. */
resetpcursor();
curson(sav); /* ready to edit */
return YES;
}
dojump()
{
int i;
putmess( "[|+|/|-|]|line|, last |C|hange, |E|nd, prior |J|ump, |M|ark; |S|et mark");
scans(ans,2);
gotoxy(59,0);
if ( (i = calcjmp()) > 0)
jumpline(i - cline);
return;
}
/* calculate jump to new line.
* interpret the jump to current line (a NOP) as full screen refresh request.
* Useful for debugging and from a remote location with transmission errors
* or outages.
*/
calcjmp()
{
int i, j, k, to;
char far *jj;
i = toupper(ans[0]);
switch (i) {
case '+':
scans(ans,5);
to = atoi( ans );
if ( to == 0) {
cleareop(0);
putpage();
}
jmpto = cline + to;
break;
case '-':
scans(ans,5);
if ( (to = atoi( ans ) ) )
jmpto = cline - to;
break;
case 'C':
if (lastc < 1) {
error("No lines have been changed");
return cline;
}
cursory = topline + SHEIGHT/2;
jmpto = lastc; /* line last changed/deleted/inserted */
break;
case 'E':
jmpto = l